package gitee.blacol.myIdUtil.builder;

import gitee.blacol.myIdUtil.entity.ComplexId;
import gitee.blacol.myIdUtil.entity.IdBuilderConfig;
import gitee.blacol.myIdUtil.entity.ObjectId;
import gitee.blacol.myIdUtil.enums.PropType;
import gitee.blacol.myIdUtil.exception.MissingNecessaryParameters;
import gitee.blacol.myIdUtil.exception.PropNotExists;

import java.lang.reflect.Field;
import java.util.*;

public class ObjectIdBuilder<OE> extends IdBuilder<ObjectId<OE>>{
    private OE obj;
    private LinkedHashMap<String, PropType> propMap;
    private String strPrefix="";
    private String strSuffix="";
    private String integerFormat="%d";
    private String doubleFormat="%.2f";
    private String dateFormat="yyyyMMdd";
    private String separator="";
    private String[] pms={"obj","prop_map","file_path"};
    private List<String> checkPropMap(HashMap<String, PropType> propMap, OE obj) {
        Class<OE> aClass = (Class<OE>) obj.getClass();
        Set<String> keySet = propMap.keySet();
        Iterator<String> iterator=keySet.iterator();
        List<String> notExistList=new ArrayList<>();
        while (iterator.hasNext()){
            String next = iterator.next();
            Field field = null;
            try {
                field = aClass.getDeclaredField(next);
                if (field==null){
                    notExistList.add(next);
                }
            } catch (NoSuchFieldException e) {
                notExistList.add(next);
            }
        }
        return notExistList;
    }
    @Override
    public IdBuilder<ObjectId<OE>> setConfig(IdBuilderConfig config) throws MissingNecessaryParameters, PropNotExists {
        boolean c1=config.containsKey(pms[0]);
        boolean c2=config.containsKey(pms[1]);
        boolean c3=config.containsKey(pms[2]);
        if (c1&&c2&&c3){
            obj=(OE) config.get("obj");
            propMap=(LinkedHashMap<String, PropType>) config.get("prop_map");
            List<String> notExistList = checkPropMap(propMap, obj);
            if (notExistList.size()>0){
                throw new PropNotExists(notExistList,obj.getClass());
            }
            if (config.get("str_prefix")!=null)
                strPrefix=(String) config.get("str_prefix");
            if (config.get("str_suffix")!=null)
                strSuffix=(String) config.get("str_suffix");
            if (config.get("integer_format")!=null)
                integerFormat=(String) config.get("integer_format");
            if (config.get("double_format")!=null)
                doubleFormat=(String) config.get("double_format");
            if (config.get("date_format")!=null)
                dateFormat=(String) config.get("date_format");
            if (config.get("use_separator")!=null)
                useSeparator=(Boolean) config.get("use_separator");

            if (config.get("index_format")!=null)
                indexFormat=(String) config.get("index_format");

            filePath=(String) config.get("file_path");
            if (useSeparator)
                separator=(String) config.get("separator");

        }else{
            throw new MissingNecessaryParameters(pms);
        }
        return this;
    }

    @Override
    public ObjectId<OE> build() {
        ObjectId<OE> id=new ObjectId<OE>();
        id.setObj(obj);
        id.setPropMap(propMap);
        id.setStrPrefix(strPrefix);
        id.setStrSuffix(strSuffix);
        id.setIntegerFormat(integerFormat);
        id.setDoubleFormat(doubleFormat);
        id.setDateFormat(dateFormat);
        if (startWith0){
            id.setIndex(0);
        }
        if (useSeparator){
            id.setSeparator(separator);
        }
        id.setIndexFormat(indexFormat);
        id.setFilePath(filePath);
        return id;
    }
}
